package com.uam.core.lk.utils;

import java.io.IOException;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.extern.slf4j.Slf4j;

/**
 * json工具类
 */
@Slf4j
public class JsonUtils {

    private final static ObjectMapper objectMapper = new ObjectMapper();

    public static ObjectMapper getInstance() {
        return objectMapper;
    }

    /**
     * <p>
     * 将一个POJO对象转换成Json字符串
     * </p>
     *
     * @param obj
     *            Java对象，Object类型
     * @return String Json字符串
     * @throws JsonProcessingException
     */
    public static String obj2Json(Object obj) throws JsonProcessingException {
        return objectMapper.writeValueAsString(obj);
    }

    /**
     * <p>
     * 将一个Json字符串转换成一个POJO对象
     * </p>
     *
     * @param jsonStr
     * @param clazz
     * @return
     * @throws IOException
     * @throws JsonParseException
     * @throws JsonMappingException
     */
    public static <T> T json2Pojo(String jsonStr, Class<T> clazz)
        throws IOException, JsonParseException,
        JsonMappingException {
        return objectMapper.readValue(jsonStr, clazz);
    }

    public static <T> T json2Pojo(byte[] bytes, Class<T> clazz)
        throws IOException, JsonParseException,
        JsonMappingException {
        return objectMapper.readValue(bytes, clazz);
    }

    /**
     * json string convert to map
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> json2Map(String jsonStr)
        throws IOException, JsonParseException,
        JsonMappingException {
        return objectMapper.readValue(jsonStr, Map.class);
    }

    /**
     * json string convert to map with javaBean
     */
    public static <T> Map<String, T> json2Map(String jsonStr, Class<T> clazz)
        throws IOException, JsonParseException,
        JsonMappingException,
        IllegalArgumentException {
        Map<String, Map<String, Object>> map = objectMapper.readValue(jsonStr,
            new TypeReference<Map<String, Map<String, Object>>>() {
            });
        Map<String, T> result = new HashMap<String, T>();
        for (Entry<String, Map<String, Object>> entry : map.entrySet()) {
            result.put(entry.getKey(), map2Pojo(entry.getValue(), clazz));
        }
        return result;
    }

    /**
     * json array string convert to list with javaBean
     */
    public static <T> List<T> json2List(String jsonArrayStr, Class<T> clazz)
        throws IOException, JsonParseException,
        JsonMappingException,
        IllegalArgumentException {
        List<Map<String, Object>> list = objectMapper.readValue(jsonArrayStr,
            new TypeReference<List<Map<String, Object>>>() {
            });
        List<T> result = new ArrayList<T>();
        for (Map<String, Object> map : list) {
            result.add(map2Pojo(map, clazz));
        }
        return result;
    }

    public static List<String> json2ListString(String json)
        throws IOException, JsonParseException,
        JsonMappingException, IllegalArgumentException {
        List<String> list = objectMapper.readValue(json, new TypeReference<List<String>>() {
        });
        return list;
    }

    public static <T> List<T> json2ListV2(String json, Class<T> clazz)
        throws IOException, JsonParseException,
        JsonMappingException, IllegalArgumentException {

        List<T> list = objectMapper.readValue(json, new TypeReference<List<T>>() {
        });
        return list;
    }

    public static <T> List<T> json2ListV2(byte[] bytes, Class<T> clazz)
        throws IOException, JsonParseException,
        JsonMappingException, IllegalArgumentException {

        List<T> list = objectMapper.readValue(bytes, new TypeReference<List<T>>() {
        });
        return list;
    }

    /**
     * map convert to javaBean
     */
    public static <T> T map2Pojo(Map map, Class<T> clazz) throws IllegalArgumentException {
        return objectMapper.convertValue(map, clazz);
    }

    public static Map<String, Object> pojo2Map(Object pojo) throws IllegalArgumentException {
        return objectMapper.convertValue(pojo, Map.class);
    }

    /***
     * 把表记录转换成Json格式
     *
     * @param rs
     * @return JSON字符串
     */
    public static String resultSet2Json(ResultSet rs) {
        String strJson = "";
        StringBuffer resultJson = new StringBuffer();
        try {
            while (rs.next()) {
                resultJson.append("{");
                for (int j = 0; j < rs.getMetaData().getColumnCount(); j++) {
                    String cn = rs.getString(j + 1);
                    resultJson.append("\"" + rs.getMetaData().getColumnName(j + 1) + "\":\"" + cn + "\"");
                    if (j < rs.getMetaData().getColumnCount() - 1)
                        resultJson.append(",");
                }
                resultJson.append("},");
            }
            if (resultJson.length() > 0) {
                strJson = resultJson.toString();
                strJson = strJson.substring(0, strJson.length() - 1);
                strJson = "[" + strJson + "]";
            }

        } catch (Exception se) {
            se.printStackTrace();
        }
        return strJson;
    }

    /**
     * javaBean,list,array convert to json string
     */
    public static String obj2Json(Object obj, ObjectMapper objectMapper) throws JsonProcessingException {
        return objectMapper.writeValueAsString(obj);
    }

    /**
     * json string convert to javaBean
     */
    public static <T> T json2Pojo(String jsonStr, Class<T> clazz, ObjectMapper objectMapper)
        throws IOException,
        JsonParseException,
        JsonMappingException {
        return objectMapper.readValue(jsonStr, clazz);
    }

    public static <T> T json2Pojo(byte[] bytes, Class<T> clazz, ObjectMapper objectMapper)
        throws IOException,
        JsonParseException,
        JsonMappingException {
        return objectMapper.readValue(bytes, clazz);
    }

    /**
     * json string convert to map
     */
    public static Map<String, Object> json2Map(String jsonStr, ObjectMapper objectMapper)
        throws IOException,
        JsonParseException,
        JsonMappingException {
        return objectMapper.readValue(jsonStr, Map.class);
    }

    /**
     * json string convert to map with javaBean
     */
    public static <T> Map<String, T> json2Map(String jsonStr, Class<T> clazz, ObjectMapper objectMapper)
        throws IOException,
        JsonParseException,
        JsonMappingException,
        IllegalArgumentException {
        Map<String, Map<String, Object>> map = objectMapper.readValue(jsonStr,
            new TypeReference<Map<String, Map<String, Object>>>() {
            });
        Map<String, T> result = new HashMap<String, T>();
        for (Entry<String, Map<String, Object>> entry : map.entrySet()) {
            result.put(entry.getKey(), map2Pojo(entry.getValue(), clazz, objectMapper));
        }
        return result;
    }

    /**
     * json array string convert to list with javaBean
     */
    public static <T> List<T> json2List(String jsonArrayStr, Class<T> clazz, ObjectMapper objectMapper)
        throws IOException,
        JsonParseException,
        JsonMappingException,
        IllegalArgumentException {
        List<Map<String, Object>> list = objectMapper.readValue(jsonArrayStr,
            new TypeReference<List<Map<String, Object>>>() {
            });
        List<T> result = new ArrayList<T>();
        for (Map<String, Object> map : list) {
            result.add(map2Pojo(map, clazz, objectMapper));
        }
        return result;
    }

    public static List<String> json2ListString(String json, ObjectMapper objectMapper)
        throws IOException,
        JsonParseException,
        JsonMappingException,
        IllegalArgumentException {
        List<String> list = objectMapper.readValue(json, new TypeReference<List<String>>() {
        });
        return list;
    }

    public static <T> List<T> json2ListV2(String json, Class<T> clazz, ObjectMapper objectMapper)
        throws IOException, JsonParseException,
        JsonMappingException, IllegalArgumentException {

        List<T> list = objectMapper.readValue(json, new TypeReference<List<T>>() {
        });
        return list;
    }

    public static <T> List<T> json2ListV2(byte[] bytes, Class<T> clazz, ObjectMapper objectMapper)
        throws IOException, JsonParseException,
        JsonMappingException, IllegalArgumentException {

        List<T> list = objectMapper.readValue(bytes, new TypeReference<List<T>>() {
        });
        return list;
    }

    /**
     * map convert to javaBean
     */
    public static <T> T map2Pojo(Map map, Class<T> clazz, ObjectMapper objectMapper) throws IllegalArgumentException {
        return objectMapper.convertValue(map, clazz);
    }

    public static Map<String, Object> pojo2Map(Object pojo, ObjectMapper objectMapper) throws IllegalArgumentException {
        return objectMapper.convertValue(pojo, Map.class);
    }

    /**
     * 把字符串转化成json格式
     * @param  jsonStr
     * @date  2019/12/9 11:28 祝展
     */
    public static String formatJsonStr(String jsonStr) {
        if (null == jsonStr || "".equals(jsonStr)) {
            return "";
        }

        StringBuilder sb = new StringBuilder();
        char current = '\0';
        int indent = 0;
        int strLength = jsonStr.length();
        for (int i = 0; i < strLength; i++) {
            current = jsonStr.charAt(i);
            switch (current) {
                case '"':
                    sb.append(current);
                    do {
                        i++;
                        char tempChar = jsonStr.charAt(i);
                        sb.append(tempChar);
                        if (tempChar == '"') {
                            break;
                        }
                    } while (true);
                    break;
                case '{':
                    sb.append(current);
                    indent++;
                    addIndentBlank(sb, indent);
                    break;
                case '}':
                    indent--;
                    addIndentBlank(sb, indent);
                    sb.append(current);
                    break;
                case ',':
                    sb.append(current);
                    addIndentBlank(sb, indent);
                    break;
                case ':':
                    sb.append(current);
                    sb.append(' ');
                    break;
                case ' ':
                    break;
                case '\t':
                    break;
                case '\n':
                    break;
                default:
                    sb.append(current);
                    break;
            }
        }
        return sb.toString();
    }

    /**
     * 填充space
     * @param  sb
     * @param  indent
     * @date  2019/12/9 11:27 祝展
     */
    public static void addIndentBlank(StringBuilder sb, int indent) {
        sb.append('\n');
        for (int i = 0; i < indent; i++) {
            sb.append('\t');
        }
    }

    private JsonUtils() {

    }
}
